package cn.zj.smart.gencode;

import cn.zj.smart.gencode.beans.ClassDef;
import cn.zj.smart.gencode.beans.FlutterBean;
import cn.zj.smart.gencode.beans.ModulePageConfig;
import cn.zj.smart.gencode.beans.PropDef;
import cn.zj.smart.gencode.util.VmUtil;
import cn.zj.smart.util.javadoc.beans.JavaDoc;
import cn.zj.smart.util.javadoc.util.JavaDocUtil;

import java.io.File;
import java.lang.reflect.Field;
import java.util.*;

/**
 * 根据精简Java类生成带get/set/builder的完整类
 */
public class GenFlutterBean {
    public static void main(String[] args) {
        final String out = "E:\\play_all\\flutter\\tally\\lib\\models";
        Class[] classes = {ModulePageConfig.class};
        for (Class aClass : classes) {
            GenFlutterBean.genFlutterBenCode(aClass,out);
        }
    }

    public static void genFlutterBenCode(Class clazz, String outFolder) {
        ClassDef classDef = getJavaClassDef(clazz);
        FlutterBean flutterBean = classDef2FlutterBean(classDef);
        String vmName = "vm/flutter/flutterBeanBuilder.vm";
        Map<String, Object> map = new HashMap<>();
        map.put("data", flutterBean);
        String outPath = outFolder+ File.separator+clazz.getSimpleName()+".dart";
        VmUtil.vmToFile(vmName,map,outPath);
    }

    private static FlutterBean classDef2FlutterBean(ClassDef classDef) {
        List<FlutterBean.FlutterProp> flutterProps = new ArrayList<>();
        Set<String> imports = new HashSet<>();
        for (PropDef propField : classDef.getPropFields()) {
            FlutterBean.FlutterProp flutterProp = new FlutterBean.FlutterProp();
            flutterProp.setName(propField.getFieldName());
            flutterProp.setDesc(propField.getJavaDoc());
            flutterProp.setArray(propField.isArray());
            flutterProp.setBean(FlutterBean.FlutterType.isBean(propField.getFieldType()));
            flutterProp.setTypeName(FlutterBean.FlutterType.findByClazz(propField.getFieldType()));
            if (flutterProp.isBean()) {
                imports.add(flutterProp.getTypeName());
            }
            flutterProps.add(flutterProp);
        }
        return FlutterBean.builder()
                .name(classDef.getName())
                .desc(classDef.getJavaDoc())
                .flutterProp(flutterProps)
                .imports(imports)
                .build();
    }

    private static ClassDef getJavaClassDef(Class clazz) {
        JavaDoc javaDoc = JavaDocUtil.getClassJavaDoc(clazz);
        List<PropDef> propDefs = new ArrayList<>();
        for (Field field : clazz.getDeclaredFields()) {
            propDefs.add(PropDef.builder()
                    .fieldName(field.getName())
                    .fieldType(JavaDocUtil.getActualType(field))
                    .array(isArrayType(field.getType()))
                    .javaDoc(javaDoc.getPropertyDocs().get(field.getName()))
                    .build());
        }
        return ClassDef.builder()
                .name(clazz.getSimpleName())
                .extendClass(clazz.getSuperclass())
                .packageName(clazz.getPackage().getName())
                .javaDoc(javaDoc.getClassDoc())
                .propFields(propDefs)
                .build();
    }

    /**
     * @param type
     * @return
     */
    private static boolean isArrayType(Class<?> type) {
        if (type.isArray()) {
            return true;
        }
        if (type.equals(List.class)) {
            return true;
        }
        if (type.equals(Set.class)) {
            return true;
        }
        return false;
    }
}
